package com.bhkj.pdjhforotherapp.core.printutilspdj;

import android.app.Activity;
import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;

import com.bhkj.pdjhforotherapp.R;
import com.bhkj.pdjhforotherapp.common.Contact;
import com.bhkj.pdjhforotherapp.common.callback.CallbackManager;
import com.bhkj.pdjhforotherapp.common.callback.IGlabolCallback;
import com.bhkj.pdjhforotherapp.common.utils.Tools;
import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.printsdk.cmd.PrintCmd;
import com.printsdk.usbsdk.UsbDriver;

import net.lemonsoft.lemonhello.LemonHello;
import net.lemonsoft.lemonhello.LemonHelloAction;
import net.lemonsoft.lemonhello.LemonHelloView;

public class UsbPrintManager {
    private UsbManager mUsbManager;
    private UsbDriver mUsbDriver;
    private UsbReceiver mUsbReceiver;
    UsbDevice mUsbDev1;        //打印机1
    UsbDevice mUsbDev2;        //打印机2
    UsbDevice mUsbDev;
    public final static int PID11 = 8211;
    public final static int PID13 = 8213;
    public final static int PID15 = 8215;
    public final static int VENDORID = 1305;
    private static final String ACTION_USB_PERMISSION = "com.usb.sample.USB_PERMISSION";
    private static final String ACTION_USB_PERMISSION_GRANTED = "com.usb.sample.action.USB_PERMISSION_GRANTED";
    private LemonHelloView mLemonView;
    private boolean isRegisterReceiver;

    private static class Holder {
        private static UsbPrintManager INSTANCE = new UsbPrintManager();
    }

    public static UsbPrintManager getInstance() {
        return Holder.INSTANCE;
    }

    public UsbPrintManager() {

    }

    public void initPrint() {
        getUsbDriverService();// 创建UsbManager ，权限，广播；usb驱动
        getMsgByLanguage();   // 常规设置
    }

    private void getUsbDriverService() {
        Application applicationByReflect = Tools.getApplicationByReflect();
        mUsbManager = (UsbManager) applicationByReflect.getSystemService(Context.USB_SERVICE);
        if (mUsbDriver == null) {
            mUsbDriver = new UsbDriver(mUsbManager, applicationByReflect);
        }
        if (mUsbReceiver == null) {
            mUsbReceiver = new UsbReceiver(mUsbDriver);
        }
        PendingIntent permissionIntent1 = PendingIntent.getBroadcast(applicationByReflect, 0,
                new Intent(ACTION_USB_PERMISSION), 0);
        mUsbDriver.setPermissionIntent(permissionIntent1);
        // Broadcast listen for new devices
        printConnStatus();    // 连接设备 Get UsbDriver(UsbManager) service
        if (!isRegisterReceiver) {
            IntentFilter filter = new IntentFilter();
            filter.addAction(ACTION_USB_PERMISSION);
            filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
            filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
            filter.addAction(ACTION_USB_PERMISSION_GRANTED);
            applicationByReflect.registerReceiver(mUsbReceiver, filter);
            isRegisterReceiver = true;
        }
    }

    // 通过系统语言判断Message显示
    String receive = "", state = ""; // 接收提示、状态类型
    String normal = "", notConnectedOrNotPopwer = "", notMatch = "",
            printerHeadOpen = "", cutterNotReset = "", printHeadOverheated = "",
            blackMarkError = "", paperExh = "", paperWillExh = "", abnormal = "";

    private void getMsgByLanguage() {
        if (Utils.isZh(Tools.getApplicationByReflect())) {
            receive = Constant.Receive_CN;
            state = Constant.State_CN;
            normal = Constant.Normal_CN;
            notConnectedOrNotPopwer = Constant.NoConnectedOrNoOnPower_CN;
            notMatch = Constant.PrinterAndLibraryNotMatch_CN;
            printerHeadOpen = Constant.PrintHeadOpen_CN;
            cutterNotReset = Constant.CutterNotReset_CN;
            printHeadOverheated = Constant.PrintHeadOverheated_CN;
            blackMarkError = Constant.BlackMarkError_CN;
            paperExh = Constant.PaperExhausted_CN;
            paperWillExh = Constant.PaperWillExhausted_CN;
            abnormal = Constant.Abnormal_CN;
        } else {
            receive = Constant.Receive_US;
            state = Constant.State_US;
            normal = Constant.Normal_US;
            notConnectedOrNotPopwer = Constant.NoConnectedOrNoOnPower_US;
            notMatch = Constant.PrinterAndLibraryNotMatch_US;
            printerHeadOpen = Constant.PrintHeadOpen_US;
            cutterNotReset = Constant.CutterNotReset_US;
            printHeadOverheated = Constant.PrintHeadOverheated_US;
            blackMarkError = Constant.BlackMarkError_US;
            paperExh = Constant.PaperExhausted_US;
            paperWillExh = Constant.PaperWillExhausted_US;
            abnormal = Constant.Abnormal_US;
        }
    }

    // Get UsbDriver(UsbManager) service
    private boolean printConnStatus() {
        boolean blnRtn = false;
        try {
            if (!mUsbDriver.isConnected()) {
                // USB线已经连接
                for (UsbDevice device : mUsbManager.getDeviceList().values()) {
                    LogUtils.d("device print:" + device.toString());
                    if ((device.getProductId() == PID11 && device.getVendorId() == VENDORID)
                            || (device.getProductId() == PID13 && device.getVendorId() == VENDORID)
                            || (device.getProductId() == PID15 && device.getVendorId() == VENDORID)) {
                        if (!mUsbManager.hasPermission(device)) {
                            LogUtils.d("打印机没有usb权限");
                            mUsbManager.requestPermission(device, PendingIntent.getBroadcast(Tools.getApplicationByReflect(),
                                    0, new Intent(ACTION_USB_PERMISSION_GRANTED), 0));
                            break;
                        }
                        blnRtn = mUsbDriver.usbAttached(device);
                        if (!blnRtn) {
                            break;
                        }
                        blnRtn = mUsbDriver.openUsbDevice(device);

                        // 打开设备
                        if (blnRtn) {
                            if (device.getProductId() == PID11) {
                                mUsbDev1 = device;
                                mUsbDev = mUsbDev1;
                                LogUtils.d("打印机:打开成功" + PID11 + mUsbDev.toString());
                            } else {
                                mUsbDev2 = device;
                                mUsbDev = mUsbDev2;
                                LogUtils.d("打印机:打开成功" + mUsbDev.toString());
                            }
//                            ToastUtils.showShort( getString(R.string.USB_Driver_Success));
                            break;
                        } else {
                            ToastUtils.showShort(StringUtils.getString(R.string.USB_Driver_Failed));
                            break;
                        }
                    }
                }
            } else {
                blnRtn = true;
            }
        } catch (Exception e) {
            ToastUtils.showShort(e.getMessage());
        }

        return blnRtn;
    }

    // 状态查询
    private boolean checkPrinterStatus(UsbDevice usbDev) {
        int iStatus = getPrinterStatus(usbDev);
        return checkStatus(iStatus) == 0;
    }

    // 检测打印机状态
    private int getPrinterStatus(UsbDevice usbDev) {
        //如果usb驱动器清空那么久重新初始化
        if (mUsbDriver == null) {
            initPrint();
        }
        int iRet = -1;

        byte[] bRead1 = new byte[1];
        byte[] bWrite1 = PrintCmd.GetStatus1();
        if (mUsbDriver.read(bRead1, bWrite1, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus1(bRead1[0]);
        }

        if (iRet != 0)
            return iRet;

        byte[] bRead2 = new byte[1];
        byte[] bWrite2 = PrintCmd.GetStatus2();
        if (mUsbDriver.read(bRead2, bWrite2, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus2(bRead2[0]);
        }

        if (iRet != 0)
            return iRet;

        byte[] bRead3 = new byte[1];
        byte[] bWrite3 = PrintCmd.GetStatus3();
        if (mUsbDriver.read(bRead3, bWrite3, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus3(bRead3[0]);
        }

        if (iRet != 0)
            return iRet;

        byte[] bRead4 = new byte[1];
        byte[] bWrite4 = PrintCmd.GetStatus4();
        if (mUsbDriver.read(bRead4, bWrite4, usbDev) > 0) {
            iRet = PrintCmd.CheckStatus4(bRead4[0]);
        }

//        byte[] bRead5 = new byte[1];
//        byte[] bWrite5 = PrintCmd.GetStatus5();
//        if (mUsbDriver.read(bRead5, bWrite5, usbDev) > 0) {
//            iRet = PrintCmd.CheckStatus4(bRead5[0]);
//        }
        return iRet;
    }


    private int checkStatus(int iStatus) {
        int iRet = -1;
        LogUtils.d("状态:" + iStatus);
        StringBuilder sMsg = new StringBuilder();

        //0 打印机正常 、1 打印机未连接或未上电、2 打印机和调用库不匹配
        //3 打印头打开 、4 切刀未复位 、5 打印头过热 、6 黑标错误 、7 纸尽 、8 纸将尽
        switch (iStatus) {
            case 0:
            case 8:
                sMsg.append(normal);       // 正常
                iRet = 0;
                break;
//            case 8:
//                sMsg.append(paperWillExh); // 纸将尽
//                iRet = 0;
//                showMessage(sMsg.toString());
//
//                break;
            case 3:
                sMsg.append(printerHeadOpen); //打印头打开
                showMessage(sMsg.toString());

                break;
            case 4:
                sMsg.append(cutterNotReset);  //切刀未复位
                showMessage(sMsg.toString());
                break;
            case 5:
                sMsg.append(printHeadOverheated); //打印头过热
                showMessage(sMsg.toString());

                break;
            case 6:
                sMsg.append(blackMarkError);  //黑标错误
                showMessage(sMsg.toString());

                break;
            case 7:
                sMsg.append(paperExh);     // 纸尽==缺纸
                showMessage(sMsg.toString());

                break;
            case 1:
                sMsg.append(notConnectedOrNotPopwer);//打印机未连接或未上电
                showMessage(sMsg.toString());

                break;
            default:
                sMsg.append(abnormal);     // 异常
                showMessage(sMsg.toString() + "-" + iRet);
                break;
        }
        return iRet;
    }

    private void showMessage(String sMsg) {
        Activity topActivity = ActivityUtils.getTopActivity();
        if (ActivityUtils.isActivityAlive(topActivity)){
            LemonHello.getInformationHello("打印机状态" + sMsg, "")
                    .addAction(new LemonHelloAction(StringUtils.getString(R.string.sure),
                            (lemonHelloView, lemonHelloInfo, lemonHelloAction) -> {
                                lemonHelloView.hide();
                                mLemonView = lemonHelloView;
                                CallbackManager instance = CallbackManager.getInstance();
                                IGlabolCallback callback = instance.getCallback(Contact.CLOSE_READ_ID);
                                if (callback != null) {
                                    callback.executeCallback("");
                                }
                            }
                    )).show(topActivity);
        }
    }

    public void closePrint() {
        hideTipDialog();
        Application application = Tools.getApplicationByReflect();
        if (isRegisterReceiver && Tools.getApplicationByReflect().getResources().getBoolean(R.bool.isQhj) && mUsbReceiver != null) {
            isRegisterReceiver = false;
            application.unregisterReceiver(mUsbReceiver);
            mUsbReceiver = null;
        }
        mUsbDriver = null;
        mUsbDev = null;
        mUsbDev1 = null;
        mUsbDev2 = null;
    }

    public UsbDriver getUsbDriver() {
        return mUsbDriver;
    }

    public boolean showPrintDeviceStatus() {
        return checkPrinterStatus(mUsbDev);
    }

    public void hideTipDialog() {
        if (mLemonView != null) {
            mLemonView.hide();
        }
    }

}
